﻿using System.Linq;
using NHibernate;
using NHibernate.Linq;
using SportStore.Core.Data;

namespace SportStore.Core.NHibernate
{
    /// <summary>
    /// Repository to implement standard data access operations for entities
    /// </summary>
    public abstract class GenericRepository<T> : IRepository<T> where T : class
    {
        #region Constants and Fields

        protected readonly ISession Session;

        #endregion

        #region Constructors and Destructors

        /// <summary>
        /// Initializes a new instance of the <see cref="GenericRepository{T}"/> class. 
        /// </summary>
        protected GenericRepository(ISession session)
        {
            this.Session = session;
        }

        #endregion

        #region Public Methods

        /// <summary>
        /// Saves the specified entity.
        /// </summary>
        public virtual void Add(T entity)
        {
            this.Session.Save(entity);
        }

        /// <summary>
        /// Deletes the specified entity.
        /// </summary>
        public virtual void Delete(T entity)
        {
            this.Session.Delete(entity);
        }

        /// <summary>
        /// Gets the given entity by id.
        /// </summary>
        public virtual T GetById(int id)
        {
            return this.Session.Get<T>(id);
        }

        /// TODO:Delete this code
        /// <summary>
        /// Gets all entities of the given type.
        /// </summary>
        /// <summary>
        /// Updates the specified entity.
        /// </summary>
        public virtual void Update(T entity)
        {
            this.Session.Update(entity);
        }

        #endregion

        #region Protected Methods

        /// <summary>
        /// Gets a queryable list for a given entity
        /// </summary>
        protected IQueryable<T> All()
        {
            return this.Session.Query<T>();
        }

        /// <summary>
        /// Creates the criteria.
        /// </summary>
        protected ICriteria CreateCriteria()
        {
            return this.Session.CreateCriteria<T>();
        }

        #endregion
    }
}
